
#include <BBase>
#include <BString>

using namespace BWE;

#ifdef linux
#include <unistd.h>
#include <iconv.h>
#include <sys/time.h>

BWEAPI BReal BWE::bTime()
{
	struct timeval tv;
	struct timezone tz;
	gettimeofday(&tv, &tz);
	return tv.tv_sec + tv.tv_usec * 0.000001;
}

BWEAPI bool BWE::bSleep(double seconds)
{
	usleep(seconds * 1000000);
	return true;
}

int utf8togb2312(char *sourcebuf,size_t sourcelen,char *destbuf,size_t destlen)
 {   
	iconv_t cd;   
	if( (cd = iconv_open("gb2312","utf-8")) ==0 )     
		return -1;  
	memset(destbuf,0,destlen);   
	char **src = &sourcebuf;   
	char **dst = &destbuf;
	if(-1 == iconv(cd, src, &sourcelen, dst, &destlen))     
		return -1;
	iconv_close(cd);   
	return 0;   
 }
BWEAPI int BWE::UTF8_To_GB2312(const BCode& code)
{
	return 0;
}
char* UTF8_To_GB2312(const BString& str)
{
	return 0;
}

BWEAPI wchar_t BWE::GB2312_To_UTF8(const BCode& code)
{
	return 0;
}
BWEAPI const char* BWE::GB2312_To_UTF8(const char* cstr)
{
	return 0;
}
#endif

#ifdef _WIN32
#include <Windows.h>

BWEAPI BReal BWE::bTime()
{
	DWORD usec = GetTickCount();
	return usec * 0.001;
}

BWEAPI bool BWE::bSleep(double seconds)
{
	DWORD ms = (DWORD)(seconds * 1000);
	Sleep(ms);
/*
	if (seconds == 0.0)
		return true;

	if (seconds < 0.0)
	{
#ifdef linux
		pthread_t handle = pthread_self();
#endif
#ifdef _WIN32
		HANDLE handle = GetCurrentThread();
#endif
		return !SuspendThread(handle);
	}

	HANDLE htimer = ::CreateWaitableTimer(0, true, 0);
	if (htimer)
		return false;
	
	LARGE_INTEGER time;
	time.QuadPart = LONGLONG(seconds * -10000000);
	
	if (::SetWaitableTimer(htimer, &time, 0, 0, 0, 0) == false)
		return false;
	
	if (::WaitForSingleObject(htimer, INFINITE) == WAIT_FAILED)
		return false;
*/
	return true;
}

BWEAPI int BWE::UTF8_To_GB2312(const BCode& code)
{
	const char* ustr = code.str();
	char cstr[5];
	int len = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, 0, 0);
	MultiByteToWideChar(CP_UTF8, 0, ustr, 4, (LPWSTR)cstr, len);

	return *(int*)cstr;
	//len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
	//char* str = new char[len + 1];
	//memset(str, 0, len + 1);
	//WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
	//if (wstr) delete[] wstr;
	//return str;
}
char* UTF8_To_GB23120(const BString& str)
{
	int len = MultiByteToWideChar(CP_UTF8, 0, str.cstr(), -1, 0, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	wstr[0] = 0;
	MultiByteToWideChar(CP_UTF8, 0, str.cstr(), -1, wstr, len);

	len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* cstr = new char[len + 1];
	memset(cstr, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, wstr, -1, cstr, len, NULL, NULL);
	if (wstr) delete[] wstr;
	return cstr;
}

BWEAPI wchar_t BWE::GB2312_To_UTF8(const BCode& code)
{
	const char* ustr = code.str();
	char cstr[3];
	cstr[0] = ustr[0];
	cstr[1] = ustr[1];
	cstr[2] = 0;
	int len = MultiByteToWideChar(CP_ACP, 0, cstr, -1, NULL, 0);
	wchar_t wstr[2];
	MultiByteToWideChar(CP_ACP, 0, cstr, -1, wstr, len);
	//len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	//char* str = new char[len + 1];
	//memset(str, 0, len + 1);
	//WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	//if (wstr) delete[] wstr;
	return wstr[0];
}
BWEAPI const char* BWE::GB2312_To_UTF8(const char* cstr)
{
	int len = MultiByteToWideChar(CP_ACP, 0, cstr, -1, NULL, 0);
	WCHAR* ustr = new WCHAR[len + 1];
	ustr[0] = 0;
	MultiByteToWideChar(CP_ACP, 0, cstr, -1, ustr, len);
	return (const char*)ustr;
}

#endif

BWEAPI const char* BWE::bCursorStr(CursorType type)
{
	switch (type)
	{
	case Cursor_None:			return "None";
	case Cursor_Arrow:			return "Arrow";
	case Cursor_Ibeam:			return "Ibeam";
	case Cursor_Cross:			return "Cross";
	case Cursor_Wait:			return "Wait";
	case Cursor_Hand:			return "Hand";
	case Cursor_Help:			return "Help";
	case Cursor_SizeVer:		return "SizeVer";
	case Cursor_SizeHor:		return "SizeHor";
	case Cursor_SizeAll:		return "SizeAll";
	case Cursor_SizeTop:		return "SizeTop";
	case Cursor_SizeLeft:		return "SizeLeft";
	case Cursor_SizeRight:		return "SizeRight";
	case Cursor_SizeBottom:		return "SizeBottom";
	case Cursor_SizeLeftTop:		return "SizeLeftTop";
	case Cursor_SizeLeftBottom:		return "SizeLeftBottom";
	case Cursor_SizeRightTop:		return "SizeRightTop";
	case Cursor_SizeRightBottom:	return "SizeRightBottom";
	case Cursor_SplitVer:		return "SplitVer";
	case Cursor_SplitHor:		return "SplitHor";
	case Cursor_Forbidden:		return "Forbidden";
	case Cursor_UpArrow:		return "UpArrow";
	case Cursor_DownArrow:		return "DownArrow";
	default:
		return "Invalid";
	}
}
